package org.wpahs.ahn.rssfeed;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Log;
import android.webkit.URLUtil;

import org.apache.http.HttpEntity;
import org.wpahs.ahn.rssfeed.DB.DBMyFeed;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

/**
 * Created by dgambone on 02/17/2015.
 */
public class SiteInfoDownloader extends AsyncTask<Void,Void,SiteInfoDownloader.SiteInfo> {
    MyFeed mFeed;
    String mSiteLink;
    String mImageFromFeed;
    private URL mSiteLinkURL;
    Context context;
    public SiteInfoDownloader(MyFeed feed, String siteLink,String imageFromFeed,Context context){
        mFeed = feed;
        mSiteLink = siteLink;
        mImageFromFeed = imageFromFeed;
        this.context = context;
        if(mSiteLink != null) {
            try {
                mSiteLinkURL = new URL(mSiteLink);
            } catch (MalformedURLException e) {
                Log.e("SiteInfoDownloader", "Malformed URL: " + mSiteLink);
            }
        }
    }

    public class SiteInfo{
        String siteLink =null;
        String feedImageUrl = null;
        public SiteInfo(String link,String feedImageUrl){
            siteLink=link;
            this.feedImageUrl = feedImageUrl;
        }
        public String appleTouchIcon = null;
        public String appleTouchIconPrecomp = null;
        public String favicon = null;
        public String downloadedImage = null;
        public String title = null;

        public String getSiteImage(){
            String retval = null;

            if(mImageFromFeed == null &&
                    appleTouchIcon == null &&
                    appleTouchIconPrecomp == null &&
                    favicon == null){
                return null;
            }
            Boolean done = false;

            while(retval == null && !done){
                if(getURL(mImageFromFeed)!= null){
                    retval= mImageFromFeed;
                    break;
                }else if(getURL(appleTouchIcon) != null){
                    retval = appleTouchIcon;
                    break;
                }else if(getURL(appleTouchIconPrecomp) != null){
                    retval = appleTouchIconPrecomp;
                    break;
                }else if(getURL(favicon) != null){
                    retval = favicon;
                    break;
                }
            }

            if(retval != null){
                //check to see it's a good URL
                try {
                    URL temp = new URL(retval);
                } catch (MalformedURLException e) {
                    // so it probably is missing the host and protocol
                    try{
                        URL temp = new URL(mSiteLink);
                        retval = temp.getProtocol() + "://" + temp.getHost() + retval;
                    }catch (MalformedURLException ex) {

                    }
                }
            }
            return retval;
        }

        private String getURL(String url){

            if(url == null) return null;
            try {
                URL temp = new URL(url);
                return temp.toExternalForm();
            } catch (MalformedURLException e) {
                //e.printStackTrace();
                //no doy.  Just want to make sure it's a good URL
                Log.i("getURL",url);
                //attempt repair.  Tack on host and portocol
                //from source site
                if(mSiteLinkURL !=null) {
                    String tempUrl = mSiteLinkURL.getProtocol() + "://" +
                            mSiteLinkURL.getHost() + url;
                    try{
                        URL temp = new URL(tempUrl);
                        return temp.toExternalForm();
                    }catch (MalformedURLException ex){
                        Log.i("getURL-FixAttempt",tempUrl);

                    }
                }
            }
            return null;
        }

        private String fixUrl(String url){
            String retval = url;

            try {
                if(!url.contains("http")){
                    URL fixUrl = new URL(mSiteLink);;
                    retval= fixUrl.getProtocol() + "://" + fixUrl.getHost() +  url;
                }
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }

            return retval;
        }

    }



    @Override
    protected SiteInfo doInBackground(Void... params) {
        //first check the fed item's url. See if the page
        //contains an "og:image" meta tag.  If it does.
        //we'll use it.  Else.  We're try to grab from the feed item

        SiteInfo siteInfo = new SiteInfo(mSiteLink, mImageFromFeed);
        String faviconUrl = null;
        if (mSiteLink != null) {
            try {
                siteInfo = findSiteInfo(mSiteLink, siteInfo);
                //see if we have an image yet is null.  If it is.  try to obtain from base URL
                if (siteInfo.appleTouchIcon == null && siteInfo.favicon == null &&
                        siteInfo.appleTouchIconPrecomp == null) {
                    //attempt to get it from the base url
                    try {
                        URL baseURL = new URL(mSiteLink);
                        siteInfo = findSiteInfo(baseURL.getProtocol() + "://" + baseURL.getHost(), siteInfo);
                    }catch (MalformedURLException e){
                        Log.e("BaseURLAttempt",e.getMessage());
                    }
                }
            } catch (Exception dex) {
                Log.e("faviconUrl", dex.getMessage());
            }
            return siteInfo;
        }
        return siteInfo;
    }


    @Override
    protected void onPostExecute(SiteInfo result) {
        super.onPostExecute(result);

            try {
                if((mFeed.getTitle() == null || mFeed.getTitle().length() == 0) && result.title != null){
                    DBMyFeed dbf = new DBMyFeed(context);
                    dbf.setTitle(mFeed.getId(),result.title);
                    dbf.close();

                }

                String faviconUrl = result.getSiteImage();
                if(faviconUrl != null){
                    Image img = new Image();
                    img.setId(mFeed.getId());
                    img.setUrl(faviconUrl);
                    img.setDownloadType(Downloader.DownloadType.FeedImage);
                    Downloader.addImageToQueue(this.context,img);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    }

    private SiteInfo findSiteInfo(String url,SiteInfo value){
        HttpEntity entity = null;
        try {
            ///*
            URL urlConnection = new URL(url);

            HttpURLConnection connection = null;
            if(!URLUtil.isHttpsUrl(url)){
                connection = (HttpURLConnection) urlConnection
                        .openConnection();

            }else{
                connection = (HttpsURLConnection) urlConnection
                        .openConnection();
            }

            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Log.i("faviconUrl", url);
            BufferedReader r = new BufferedReader(new InputStreamReader(input));
            String line;
            String linkStart = "<link";
            String metaStart = "<meta";
            String end = ">";
            int startPos;
            while ((line = r.readLine()) != null) {
                int endPos = 0;
                while ((startPos = line.indexOf(metaStart, endPos)) != -1) {
                    endPos = line.indexOf(end, startPos + metaStart.length());
                    if (endPos != -1) {
                        String imgElement = line.substring(startPos, endPos);
                        String propertyValue = getAttributeValue(imgElement, "property");
                        if (propertyValue != null && propertyValue.equals("og:site_name")) {
                            String contentValue = getAttributeValue(imgElement, "content");
                                value.title = (value.title == null ? contentValue : value.title);
                                break;
                        }
                    }else{
                        break;
                    }
                }
                endPos = 0;
                while ((startPos = line.indexOf(linkStart, endPos)) != -1) {
                    endPos = line.indexOf(end, startPos + linkStart.length());
                    if (endPos != -1) {
                        String linkElement =
                                line.substring(startPos, endPos);
                        String propertyValue = getAttributeValue(linkElement, "rel");
                        //apple-touch-icon - first try to get the apple touch icon.  it's nicer
                        if (propertyValue != null && propertyValue.toLowerCase().equals("apple-touch-icon")) {
                            String contentValue = getAttributeValue(linkElement, "href");
                            if (contentValue != null) {
                                Log.i("faviconUrl-apple touch", contentValue);
                                value.appleTouchIcon = contentValue;
                            }
                        }
                        else if(propertyValue != null && propertyValue.toLowerCase().equals("apple-touch-icon-precomposed")) {
                            String contentValue = getAttributeValue(linkElement, "href");
                            if (contentValue != null) {
                                Log.i("apple-icon-touch-pre", contentValue);
                                value.appleTouchIconPrecomp = contentValue;
                            }
                        }
                        else if (propertyValue != null && propertyValue.toLowerCase().equals("shortcut icon")) {
                            String contentValue = getAttributeValue(linkElement, "href");
                            if (contentValue != null) {
                                value.favicon = contentValue;
                                Log.i("faviconUrl", contentValue);
                            }
                        }
                    }else{
                        break;
                    }
                }
                //found both so breka
                if(value.favicon != null && value.appleTouchIcon !=null && value.appleTouchIconPrecomp != null && value.title !=null) break;
            }

        }catch (IOException ioEx) {
            Log.e("findFavicons", "" +
                            (ioEx.getMessage() != null ? ioEx.getMessage() : "Mystery Error")
            );
        }catch (Exception ex){
            Log.e("findFavicons", "" +
                            (ex.getMessage() != null ? ex.getMessage() : "Mystery Error")
            );
        }finally {
            if(entity !=null){
                try {
                    entity.consumeContent();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //System.gc();
        }
        return value;
    }

    private String getAttributeValue(String elementText,String attr){

        String propertyAttrib = attr + "=\"";
        String propertyValue = null;
        int propStart = elementText.indexOf(propertyAttrib);
        if (propStart != -1) {
            int propEnd = elementText.indexOf("\"", propStart + propertyAttrib.length());
            if (propEnd != -1) {
                ;
                propertyValue = elementText.substring(propStart + propertyAttrib.length(), propEnd);
            }
        }
        return propertyValue;
    }
}

